package pl.edu.agh.ki.ewywiadowka.client.windows.educator;

import java.util.LinkedList;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.gen2.table.client.FixedWidthFlexTable;
import com.google.gwt.gen2.table.client.FixedWidthGrid;
import com.google.gwt.gen2.table.client.ScrollTable;
import com.google.gwt.gen2.table.client.AbstractScrollTable.SortPolicy;
import com.google.gwt.gen2.table.override.client.HTMLTable.RowFormatter;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DockPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.SourcesTableEvents;
import com.google.gwt.user.client.ui.TableListener;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.datepicker.client.DateBox;

import pl.edu.agh.ki.ewywiadowka.client.Const;
import pl.edu.agh.ki.ewywiadowka.client.EWywiadowka;
import pl.edu.agh.ki.ewywiadowka.client.dto.ClassDTO;
import pl.edu.agh.ki.ewywiadowka.client.dto.MarkDTO;
import pl.edu.agh.ki.ewywiadowka.client.dto.StudentDTO;
import pl.edu.agh.ki.ewywiadowka.client.dto.SubjectDTO;
import pl.edu.agh.ki.ewywiadowka.client.dto.TeacherDTO;
import pl.edu.agh.ki.ewywiadowka.client.windows.GenericWindow;
import pl.edu.agh.ki.ewywiadowka.client.windows.SearchStudentWindow;
import pl.edu.agh.ki.ewywiadowka.client.windows.secretary.ModifyStudentWindow;

public class SingleMarksWindow extends GenericWindow implements ClickHandler,
		TableListener {

	private Grid _addMarkGrid = new Grid(2, 3);
	private VerticalPanel _marksVerticalPanel = new VerticalPanel();
	private HorizontalPanel _addMarkHorizontalPanel = new HorizontalPanel();

	private Grid _barGrid = new Grid(3, 2);
	private ScrollPanel _mainPanel = new ScrollPanel();
	private DockPanel _dockPanel = new DockPanel();

	private ScrollTable _scrollTable = null;
	private FixedWidthGrid _dataTable;
	private FixedWidthFlexTable _headerTable;

	private Button _removeButton = new Button("Usun ocene");
	private Button _addButton = new Button("Dodaj ocene");

	private int _selectedRow = -1;

	private LinkedList<MarkDTO> _marks = null;

	private SingleMarksWindow _me = null;

	private ListBox _valueListBox = new ListBox();
	private ListBox _weightListBox = new ListBox();
	private DateBox _dateBox = new DateBox();

	private StudentDTO _student = null;
	private SubjectDTO _subject = null;
	private TeacherDTO _teacher = null;
	
	private int _mode = -1;

	public SingleMarksWindow(EWywiadowka wywiadowka, StudentDTO student,
			SubjectDTO subject, int mode) {
		super(wywiadowka);

		_me = this;
		_mode = mode;

		_student = student;
		_subject = subject;

		_barGrid.setWidget(0, 0, new Label("Uczeń: "));
		_barGrid.setWidget(0, 1, new Label(student.toString() + "; "
				+ student.clas.toString()));
		_barGrid.setWidget(1, 0, new Label("Przedmiot: "));
		_barGrid.setWidget(1, 1, new Label(subject.toString()));
		_barGrid.setWidget(2, 0, new Label("Nauczyciel: "));

		Const.eWywiadowkaService.getSubjectTeacherForClass(subject, student,
				new AsyncCallback<TeacherDTO>() {

					@Override
					public void onFailure(Throwable caught) {
						Window.alert(caught.getMessage());
					}

					@Override
					public void onSuccess(TeacherDTO result) {
						if (result != null) {
							_teacher = result;
							_barGrid.setWidget(2, 1, new Label(_teacher
									.toString()));
						}
					}

				});

		_dataTable = new FixedWidthGrid(0, 3);
		_dataTable.setBorderWidth(1);

		_headerTable = new FixedWidthFlexTable();
		_headerTable.setBorderWidth(1);
		fillHeader();

		_scrollTable = new ScrollTable(_dataTable, _headerTable);
		_scrollTable.fillWidth();
		_scrollTable.setHeight("400px");

		_removeButton.addClickHandler(this);

		_marksVerticalPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		_marksVerticalPanel.add(_scrollTable);
		
			//_marksVerticalPanel.add(_removeButton);

		_addButton.addClickHandler(this);

		_addMarkGrid.setWidget(0, 0, new Label("Ocena"));
		_addMarkGrid.setWidget(0, 1, new Label("Waga"));
		_addMarkGrid.setWidget(0, 2, new Label("Data"));

		for (Integer i = 1; i <= 6; i++)
			_valueListBox.addItem(i.toString());

		for (Integer i = 1; i <= 10; i++)
			_weightListBox.addItem(i.toString());

		_addMarkGrid.setWidget(1, 0, _valueListBox);
		_addMarkGrid.setWidget(1, 1, _weightListBox);
		_addMarkGrid.setWidget(1, 2, _dateBox);
		
		_addMarkHorizontalPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_BOTTOM);
		if (_mode == 1)
			_addMarkHorizontalPanel.add(_removeButton);
		_addMarkHorizontalPanel.add(_addMarkGrid);
		_addMarkHorizontalPanel.add(_addButton);

		_dockPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		_dockPanel.add(_barGrid, DockPanel.NORTH);
		_dockPanel.add(_marksVerticalPanel, DockPanel.CENTER);
		if (mode == 1)
			_dockPanel.add(_addMarkHorizontalPanel, DockPanel.SOUTH);

		_mainPanel.add(_dockPanel);

		this.initWidget(_mainPanel);

		Const.eWywiadowkaService.getSingleMarks(_student, _subject,
				new AsyncCallback<LinkedList<MarkDTO>>() {

					@Override
					public void onFailure(Throwable caught) {
						Window.alert(caught.getMessage());
					}

					@Override
					public void onSuccess(LinkedList<MarkDTO> result) {
						getResuls(result);
					}

				});
	}

	private void getResuls(LinkedList<MarkDTO> marks) {
		_marks = marks;

		_headerTable = new FixedWidthFlexTable();
		_headerTable.setBorderWidth(1);
		fillHeader();

		_dataTable = new FixedWidthGrid(_marks.size(), 3);
		_dataTable.setBorderWidth(1);
		repaintTable();

		_dockPanel.remove(_marksVerticalPanel);

		_scrollTable = new ScrollTable(_dataTable, _headerTable);
		_scrollTable.setHeight("400px");
		_scrollTable.setWidth(this.getOffsetWidth() - 50 + "px");
		_scrollTable.setVisible(true);

		_dataTable.addTableListener(_me);
		_scrollTable.setSortPolicy(SortPolicy.DISABLED);

		_marksVerticalPanel
				.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);

		_marksVerticalPanel.clear();
		_marksVerticalPanel.add(_scrollTable);
		if (_mode == 1)
			_marksVerticalPanel.add(_removeButton);

		_dockPanel.add(_marksVerticalPanel, DockPanel.CENTER);
		_scrollTable.fillWidth();
		_scrollTable.setVisible(true);
	}

	private void repaintTable() {
		int i = 0;
		for (MarkDTO mark : _marks)
			fillRow(i++, mark);
	}

	private void fillRow(int row, MarkDTO mark) {

		RowFormatter rowFormatter = _dataTable.getRowFormatter();

		if (row % 2 == 0)
			rowFormatter.addStyleName(row, "tableRowStyle1");
		else
			rowFormatter.addStyleName(row, "tableRowStyle2");

		_dataTable.setHTML(row, 0, mark.value.toString());
		_dataTable.setHTML(row, 1, mark.weight.toString());
		_dataTable.setHTML(row, 2, mark.date.toString());
	}

	private void fillHeader() {
		_headerTable.setHTML(0, 0, "Ocena");
		_headerTable.setHTML(0, 1, "Waga");
		_headerTable.setHTML(0, 2, "Data");
	}

	@Override
	public void onCellClicked(SourcesTableEvents sender, int row, int cell) {
		RowFormatter rowFormatter = _dataTable.getRowFormatter();
		if (_selectedRow != -1) {
			if (_selectedRow % 2 == 0)
				rowFormatter.setStyleName(_selectedRow, "tableRowStyle1");
			else
				rowFormatter.setStyleName(_selectedRow, "tableRowStyle2");
		}
		_selectedRow = row;
		rowFormatter.setStyleName(row, "clickedTableRowStyle");
	}

	@Override
	public void onClick(ClickEvent event) {

		if (event.getSource() == _removeButton) {
			if (_selectedRow == -1) {
				Window.alert("Nie wybrano oceny");
			} else {
				final MarkDTO mark = _marks.get(_selectedRow);

				Const.eWywiadowkaService.removeSingleMark(mark,
						new AsyncCallback<Boolean>() {

							@Override
							public void onFailure(Throwable caught) {
								Window.alert(caught.getMessage());
							}

							@Override
							public void onSuccess(Boolean result) {
								Window.alert(result ? "Usunieto"
										: "Blad usuwania");

								_selectedRow = -1;
								Const.eWywiadowkaService
										.getSingleMarks(
												_student,
												_subject,
												new AsyncCallback<LinkedList<MarkDTO>>() {

													@Override
													public void onFailure(
															Throwable caught) {
														Window.alert(caught
																.getMessage());
													}

													@Override
													public void onSuccess(
															LinkedList<MarkDTO> result) {
														getResuls(result);
													}
												});
							}

						});
			}
		} else if (event.getSource() == _addButton) {
			if (_dateBox.getValue() == null)
				Window.alert("Prosze wybrac poprawna date");
			else {
				final MarkDTO mark = new MarkDTO(null, Integer
						.parseInt(_valueListBox.getItemText(_valueListBox
								.getSelectedIndex())), _dateBox.getValue(),
						Integer
								.parseInt(_weightListBox
										.getItemText(_weightListBox
												.getSelectedIndex())),
						_student, _subject);

				Const.eWywiadowkaService.addSingleMark(mark, _teacher,
						new AsyncCallback<Boolean>() {

							@Override
							public void onFailure(Throwable caught) {
								Window.alert(caught.getMessage());
							}

							@Override
							public void onSuccess(Boolean result) {
								Window.alert(result ? "Dodano"
										: "Blad dodawania");
								Const.eWywiadowkaService
										.getSingleMarks(
												_student,
												_subject,
												new AsyncCallback<LinkedList<MarkDTO>>() {

													@Override
													public void onFailure(
															Throwable caught) {
														Window.alert(caught
																.getMessage());
													}

													@Override
													public void onSuccess(
															LinkedList<MarkDTO> result) {
														getResuls(result);
													}
												});
							}

						});
			}
		}
	}
}
